//
//  SPCanvasView.m
//  SPMapKit
//
//  Created by zhangbo on 2017/9/8.
//  Copyright © 2017年 zhangbo. All rights reserved.
//

#import "SPCanvasView.h"

@implementation SPCanvasView

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        self.backgroundColor = [UIColor clearColor];
        _annotations = [[NSMutableArray alloc] init];
        _overlays = [[NSMutableArray alloc] init];
        _annotationViewCache = [[NSMutableDictionary alloc] init];
        _overlayRenderCache = [[NSMutableDictionary alloc] init];
    }
    
    return self;
}

-(void) addAnnotation:(id<MKAnnotation>) annotation
{
    [_annotations addObject:annotation];
}

-(void) removeAnnotation:(id<SPAnnotation>) annotation
{
    SPAnnotationView *spView = [_annotationViewCache objectForKey:[annotation identityKey]];
    [spView removeFromSuperview];
    
    [_annotationViewCache removeObjectForKey:[annotation identityKey]];
    [_annotations removeObject:annotation];
}

-(void) removeAllAnnotations
{
    for (SPAnnotationView *spView in _annotationViewCache.allValues) {
        [spView removeFromSuperview];
    }
    [_annotationViewCache removeAllObjects];
    [_annotations removeAllObjects];
}

-(void) addOverlay:(id<SPOverlay>) overlay
{
    if (![_overlays containsObject:overlay]) {
        [_overlays addObject:overlay];
    }
    
    [self setNeedsDisplay];
}

-(void) removeOverlay:(id<SPOverlay>) overlay
{
    [_overlays removeObject:overlay];
    [self setNeedsDisplay];
}

-(void) removeALLOverlays
{
    [_overlays removeAllObjects];
    [self setNeedsDisplay];
}

-(NSMutableArray*) annotations
{
    return _annotations;
}

-(NSMutableArray*) overlays
{
    return _overlays;
}

-(void) refresh;
{
    [self setNeedsDisplay];
    
    if (self.delegate) {
        for (id<SPAnnotation> anno in _annotations) {
            CGPoint screenPosition = [self.delegate GPSToScreenPosition:anno.coordinate];
            SPAnnotationView *spView = [_annotationViewCache objectForKey:[anno identityKey]];
            if (spView == nil) {
                spView = [self.delegate viewForAnnotation:anno];
                [_annotationViewCache setValue:spView forKey:[anno identityKey]];
            }
            if (CGRectContainsPoint(self.bounds, screenPosition)) {
                if (spView) {
                    switch (spView.spAnnotationViewAlign) {
                        case SPAlignCenter:
                            spView.center = screenPosition;
                            break;
                        case SPAlignTop:
                            screenPosition.y += spView.frame.size.height / 2;
                            spView.center = screenPosition;
                            break;
                        case SPAlignBottom:
                            screenPosition.y -= spView.frame.size.height / 2;
                            spView.center = screenPosition;
                            break;
                            
                        default:
                            spView.center = screenPosition;
                            break;
                    }
                    if (!spView.isInteract) {
                        [self addSubview:spView];
                    }else{
                        [self.superview addSubview:spView];
                    }
                }
            }else{
                [spView removeFromSuperview];
            }
        }
    }
}

-(void) refresh:(id<SPAnnotation>) anno
{
    // 列表没有就直接返回
    if (![_annotations containsObject:anno]) {
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        CGPoint screenPosition = [self.delegate GPSToScreenPosition:anno.coordinate];
        SPAnnotationView *spView = [_annotationViewCache objectForKey:[anno identityKey]];
        if (spView == nil) {
            spView = [self.delegate viewForAnnotation:anno];
            [_annotationViewCache setValue:spView forKey:[anno identityKey]];
            return;
        }
        if (CGRectContainsPoint(self.bounds, screenPosition)) {
            if (spView) {
                switch (spView.spAnnotationViewAlign) {
                    case SPAlignCenter:
                        spView.center = screenPosition;
                        break;
                    case SPAlignTop:
                        screenPosition.y += spView.frame.size.height / 2;
                        spView.center = screenPosition;
                        break;
                    case SPAlignBottom:
                        screenPosition.y -= spView.frame.size.height / 2;
                        spView.center = screenPosition;
                        break;
                        
                    default:
                        spView.center = screenPosition;
                        break;
                }
                if (!spView.isInteract) {
                    [self addSubview:spView];
                }else{
                    [self.superview addSubview:spView];
                }
            }
        }else{
            [spView removeFromSuperview];
        }
    });
}

-(void) refreshOverlay
{
    [self setNeedsDisplay];
}

-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesBegan");
    [super touchesBegan:touches withEvent:event];
    
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

-(void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesMoved");
    [super touchesMoved:touches withEvent:event];
    
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

-(void) touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesEnded");
    [super touchesEnded:touches withEvent:event];
    
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    for (id<SPOverlay> overlay in _overlays) {
        SPOverlayRenderer *render = [_overlayRenderCache objectForKey:[overlay identityKey]];
        if (render == nil) {
            render = [self.delegate rendererForOverlay:overlay];
            [_overlayRenderCache setValue:render forKey:[overlay identityKey]];
        }
        render.overlay = overlay;
        
        [render drawRect:rect context:context];
    }
}

-(SPAnnotationView*) getAnnotatioinView:(id<SPAnnotation>) annotation
{
    return [_annotationViewCache objectForKey:[annotation identityKey]];
}

-(NSArray*) getOverlayScreenPointList:(id<SPOverlay>) overlay
{
    SPOverlayRenderer *render = [_overlayRenderCache objectForKey:[overlay identityKey]];
    render.overlay = overlay;
    
    return [render overlayScreenPointList];
}

@end
